/* components */
import { Loading } from 'element-ui';
/* enum */
import ComponentNameEnum from '@model/enum/ComponentNameEnum';
/* model */
import { SettingGPTServiceTypeEnum } from '@gpt/model';
import BaseContact, { 
  BaseSelectUserModeEnum, 
  BaseSelectUserResult, 
  BaseSelectUserSelectedItemType, 
  BaseSelectUserTypeIdEnum, 
  SelectUserComponentDepartment, 
  SelectUserComponentRole, 
  SelectUserComponentServiceProvider, 
  SelectUserComponentUser 
} from '@src/component/common/BaseSelectUser';
/* hooks */
import { useFetchSettingGPTRobotAppRangeInsert, useInitXiaoBaoChat } from '@gpt/hooks';
/* vue */
import { defineComponent } from "vue";
/* scss */
import '@src/modules/setting/gpt/components/service-card-item.scss';
/* types */
import { PropType } from 'vue';
import { SettingGPTServiceItem, ShbGptRobotAppRangeForm } from '@src/modules/setting/gpt/types';
/* utils */
import { isFalsy } from '@src/util/type';
import { getLocalesOssUrl } from '@src/util/assets'
import { RobotAppRangeInsertModel } from '@model/param/in/AI';
import MsgModel from '@model/MsgModel';
import { uuid } from 'pub-bbx-utils';
import { message } from '@src/util/message';

enum SettingGPTServiceCardItemEventEnum {
  Update = 'update',
  Click = 'click',
  Delete = 'delete'
}

export default defineComponent({
  name: ComponentNameEnum.SettingGPTServiceCardItem,
  components: {
    
  },
  props: {
    value: {
      type: Object as PropType<SettingGPTServiceItem>,
      default: () => ({})
    },
    index: {
      type: Number,
      default: 0
    },
    disabled: {
      type: Boolean,
      default: false
    },
    isShowBottom: {
      type: Boolean,
      default: true
    },
    isSystemRobot: {
      type: Boolean,
      default: false
    },
    onDelete: {
      type: Function
    },
    onClick: {
      type: Function
    },
    onUpdate: {
      type: Function
    }
  },
  setup(props, { emit }) {
    
    const {
      loading,
      fetchRobotAppRangeInsert,
      isSuccess
    } = useFetchSettingGPTRobotAppRangeInsert()
    
    const { initChat } = useInitXiaoBaoChat()
    
    return {
      loading,
      fetchRobotAppRangeInsert,
      initChat,
      isSuccess
    }
    
  },
  data() {
    return {
      rangeKey: uuid()
    }
  },
  computed: {
    isSystem(): boolean {
      return Boolean(this.value.system)
    },
    isShowDelete(): boolean {
      // 系统机器人只允许删除 非系统服务
      if (this.isSystemRobot) {
        return isFalsy(this.isSystem) && isFalsy(this.disabled)
      }
      // 自定义机器人可以删除
      return true
    },
    isShowJumpIcon(): boolean {
      return Boolean(this.value.hasUrl) && isFalsy(this.disabled)
    },
    iconImage(): string {
      const fileName = 'xiao_bao_' + this.value.type + '.png'
      return getLocalesOssUrl(fileName)
    },
    isCommonQA(): boolean {
      return this.value.type === SettingGPTServiceTypeEnum.Common
    },
    selectedAll(): BaseSelectUserSelectedItemType[] {
      
      const tags = this.rangeForm.tags || []
      const roles = this.rangeForm.roles || []
      const providers = this.rangeForm.providers || []
      const users = this.rangeForm.users || []
      
      const typeTags = tags.map(tag => {
        return {
          ...tag,
          typeId: BaseSelectUserTypeIdEnum.Department
        }
      })
      
      const typeRoles = roles.map(role => {
        return {
          ...role,
          typeId: BaseSelectUserTypeIdEnum.Role
        }
      })
      
      const typeProviders = providers.map(provider => {
        return {
          ...provider,
          typeId: BaseSelectUserTypeIdEnum.ServiceProvider
        }
      })
      
      const typeUsers = users.map(user => {
        return {
          ...user,
          typeId: BaseSelectUserTypeIdEnum.User
        }
      })
      
      return [
        ...typeTags,
        ...typeRoles,
        ...typeProviders,
        ...typeUsers
      ]
    },
    rangeForm(): ShbGptRobotAppRangeForm {
      return this.value.rangeVO?.rangeForm || {
        users: [],
        tags: [],
        providers: [],
        roles: []
      }
    }
  },
  methods: {
    buildInsertRobotAppRangeParams(
      users: SelectUserComponentUser[],
      depts: SelectUserComponentDepartment[],
      serviceProviders: SelectUserComponentServiceProvider[],
      roles: SelectUserComponentRole[]
    ): RobotAppRangeInsertModel {
      
      const userIds = users.map(user => user.userId)
      const tagIds = depts.map(dept => dept.id)
      const serviceProviderIds = serviceProviders.map(serviceProvider => serviceProvider.id)
      const roleIds = roles.map(role => role.id)
      
      return {
        robotAppId: this.value.id as number,
        rangeForm: {
          userIds,
          tagIds,
          serviceProviderIds,
          roleIds
        }
      }
    },
    insertRobotAppRangeHandler(params: RobotAppRangeInsertModel) {
      
      const loading = Loading.service({
        lock: true
      })
      
      return this.fetchRobotAppRangeInsert(params)
        .catch(err => {
          console.error(err)
        })
        .finally(() => {
          loading.close()
        })
      
    },
    updateRobotAppRangeForm(
      users: SelectUserComponentUser[],
      depts: SelectUserComponentDepartment[],
      serviceProviders: SelectUserComponentServiceProvider[],
      roles: SelectUserComponentRole[]
    ) {
      
      if (!this.value.rangeVO) {
        return 
      }
      
      this.value.rangeVO.rangeForm = {
        users,
        tags: depts,
        providers: serviceProviders,
        roles
      }
      
    },
    onClickHandler() {
      
      if (this.disabled) {
        return
      }
      
      this.$emit(SettingGPTServiceCardItemEventEnum.Click, this.value)
    },
    onDeleteHandler() {
      this.$emit(SettingGPTServiceCardItemEventEnum.Delete, this.value)
    },
    /** 
     * @description 打开选人组件弹窗
    */
    async openSelectRangeDialog() {
      
      if (this.disabled) {
        console.warn('not allow to open select range dialog')
        return
      }
      
      const options = {
        max: -1,
        selectedAll: this.selectedAll || [],
        mode: BaseSelectUserModeEnum.Filter,
        asyncConfirm: async (checkedItemList: BaseSelectUserSelectedItemType[]) => {
          
          const isHasChecked = Boolean(checkedItemList.length)
          
          if (isFalsy(isHasChecked)) {
            message.error('请选择')
          }
          
          return isHasChecked
        }
      }
      
      const res = await BaseContact.props.multi.all(options)
      const data = res.data || {
        users: [],
        depts: [],
        serviceProviders: []
      } as unknown as BaseSelectUserResult
      
      let users = data.users || []
      let depts = data.depts || []
      let serviceProviders = data.serviceProviders || []
      let roles = data.roles || []
      
      const params = this.buildInsertRobotAppRangeParams(
        users,
        depts,
        serviceProviders,
        roles
      )
      
      const isSuccess = await this.insertRobotAppRangeHandler(params)
      if (isFalsy(isSuccess)) {
        return
      }
      
      this.$message.success('添加成功')
      
      this.updateRobotAppRangeForm(
        users,
        depts,
        serviceProviders,
        roles
      )
      
      this.initChat()
    },
    renderBottom() {
      
      if (this.isCommonQA) {
        return (
          <div class={`${ComponentNameEnum.SettingGPTServiceCardItem}-bottom-system`}>
            此能力暂不支持配置
          </div>
        )
      }
      
      return (
        <div 
          class={`${ComponentNameEnum.SettingGPTServiceCardItem}-bottom-used`}
          key={this.rangeKey}
        >
          
          <div 
            class={`${ComponentNameEnum.SettingGPTServiceCardItem}-bottom-used-top`}
            onClick={this.openSelectRangeDialog}
          >
            使用人员 
            <i class="iconfont icon-right1"></i>
          </div>
          
          <div class={`${ComponentNameEnum.SettingGPTServiceCardItem}-bottom-used-list`}>
            { this.renderBottomUsedList() }
          </div>
          
        </div>
      )
      
    },
    renderBottomUsedList() {
      
      const names = this.selectedAll.map(item => {
        // @ts-ignore
        const name = item.name || item.displayName
        return name
      })
      
      return names.join('、')
    },
    renderBottomContent() {
      
      if (isFalsy(this.isShowBottom)) {
        return
      }
      
      return (
        <div class={`${ComponentNameEnum.SettingGPTServiceCardItem}-bottom`}>
          { this.renderBottom() }
        </div>
      )
      
    }
  },
  render() {
    return (
      <div class={ComponentNameEnum.SettingGPTServiceCardItem}>
        
        <div class={`${ComponentNameEnum.SettingGPTServiceCardItem}-top`}>
          
          <div class={`${ComponentNameEnum.SettingGPTServiceCardItem}-left`}>
            <img src={this.iconImage} alt=""/>
          </div>
          
          <div class={`${ComponentNameEnum.SettingGPTServiceCardItem}-right`}>
            
            <div class={`${ComponentNameEnum.SettingGPTServiceCardItem}-title`}>
              
              <span 
                class={`${ComponentNameEnum.SettingGPTServiceCardItem}-name`}
                onClick={this.onClickHandler}
              >
                {this.value.name}
                {this.isShowJumpIcon && (
                  <i class="iconfont icon-right"></i>
                )}
              </span>
              
              <span 
                class={`${ComponentNameEnum.SettingGPTServiceCardItem}-delete`}
                onClick={this.onDeleteHandler}
              >
                {this.isShowDelete && (
                  <i class="iconfont icon-delete"></i>
                )}
              </span>
              
            </div>
            
            <div class={`${ComponentNameEnum.SettingGPTServiceCardItem}-description`}>
              {this.value.description}
            </div>
            
            <div class={`${ComponentNameEnum.SettingGPTServiceCardItem}-description`}>
              {this.value.descriptionBottom}
            </div>
            
          </div>
          
        </div>
        
        { this.renderBottomContent() }
        
      </div>
    )
  }
});